Expand description

DCV color primitives is a library to perform image color model conversion.

It is able to convert the following pixel formats:

Source pixel formatDestination pixel formats
ARGBI420, I444, NV12
BGRI420, I444, NV12, RGB
BGRAI420, I444, NV12, RGB
I420BGRA
I444BGRA
NV12BGRA
RGBBGRA

The supported color models are:

  • ycbcr, ITU-R Recommendation BT.601 (standard video system)
  • ycbcr, ITU-R Recommendation BT.709 (CSC systems)

Both standard range (0-235) and full range (0-255) are supported.

Examples

Initialize the library:

use dcv_color_primitives as dcp;
dcp::initialize();

Convert an image from bgra to nv12 (single plane) format, with Bt601 color space:

use dcv_color_primitives as dcp;
use dcp::{convert_image, ColorSpace, ImageFormat, PixelFormat};

fn convert() {
    dcp::initialize();

    const WIDTH: u32 = 640;
    const HEIGHT: u32 = 480;

    let src_buffers: &[&[u8]] = &[&[0u8; 4 * (WIDTH as usize) * (HEIGHT as usize)]];
    let dst_buffers: &mut [&mut [u8]] =
        &mut [&mut [0u8; 3 * (WIDTH as usize) * (HEIGHT as usize) / 2]];

    let src_format = ImageFormat {
        pixel_format: PixelFormat::Bgra,
        color_space: ColorSpace::Lrgb,
        num_planes: 1,
    };

    let dst_format = ImageFormat {
        pixel_format: PixelFormat::Nv12,
        color_space: ColorSpace::Bt601,
        num_planes: 1,
    };

    convert_image(
        WIDTH,
        HEIGHT,
        &src_format,
        None,
        src_buffers,
        &dst_format,
        None,
        dst_buffers,
    );
}

Handle conversion errors:

use dcv_color_primitives as dcp;
use dcp::{convert_image, ColorSpace, ImageFormat, PixelFormat};
use std::error;

fn convert() -> Result<(), Box<dyn error::Error>> {
    dcp::initialize();

    const WIDTH: u32 = 640;
    const HEIGHT: u32 = 480;

    let src_buffers: &[&[u8]] = &[&[0u8; 4 * (WIDTH as usize) * (HEIGHT as usize)]];
    let dst_buffers: &mut [&mut [u8]] =
        &mut [&mut [0u8; 3 * (WIDTH as usize) * (HEIGHT as usize) / 2]];

    let src_format = ImageFormat {
        pixel_format: PixelFormat::Bgra,
        color_space: ColorSpace::Bt709,
        num_planes: 1,
    };

    let dst_format = ImageFormat {
        pixel_format: PixelFormat::Nv12,
        color_space: ColorSpace::Bt601,
        num_planes: 1,
    };

    convert_image(
        WIDTH,
        HEIGHT,
        &src_format,
        None,
        src_buffers,
        &dst_format,
        None,
        dst_buffers,
    )?;

    Ok(())
}

Compute how many bytes are needed to store and image of a given format and size:

use dcv_color_primitives as dcp;
use dcp::{get_buffers_size, ColorSpace, ImageFormat, PixelFormat};
use std::error;

fn compute_size() -> Result<(), Box<dyn error::Error>> {
    dcp::initialize();

    const WIDTH: u32 = 640;
    const HEIGHT: u32 = 480;
    const NUM_PLANES: u32 = 1;

    let format = ImageFormat {
        pixel_format: PixelFormat::Bgra,
        color_space: ColorSpace::Lrgb,
        num_planes: NUM_PLANES,
    };

    let sizes: &mut [usize] = &mut [0usize; NUM_PLANES as usize];
    get_buffers_size(WIDTH, HEIGHT, &format, None, sizes)?;

    let buffer: Vec<_> = vec![0u8; sizes[0]];

    // Do something with buffer
    // --snip--

    Ok(())
}

Provide image planes to hangle data scattered in multiple buffers that are not necessarily contiguous:

use dcv_color_primitives as dcp;
use dcp::{convert_image, get_buffers_size, ColorSpace, ImageFormat, PixelFormat};
use std::error;

fn convert() -> Result<(), Box<dyn error::Error>> {
    dcp::initialize();

    const WIDTH: u32 = 640;
    const HEIGHT: u32 = 480;
    const NUM_SRC_PLANES: u32 = 2;
    const NUM_DST_PLANES: u32 = 1;

    let src_format = ImageFormat {
        pixel_format: PixelFormat::Nv12,
        color_space: ColorSpace::Bt709,
        num_planes: NUM_SRC_PLANES,
    };

    let src_sizes: &mut [usize] = &mut [0usize; NUM_SRC_PLANES as usize];
    get_buffers_size(WIDTH, HEIGHT, &src_format, None, src_sizes)?;

    let src_y: Vec<_> = vec![0u8; src_sizes[0]];
    let src_uv: Vec<_> = vec![0u8; src_sizes[1]];
    let src_buffers: &[&[u8]] = &[&src_y[..], &src_uv[..]];

    let dst_format = ImageFormat {
        pixel_format: PixelFormat::Bgra,
        color_space: ColorSpace::Lrgb,
        num_planes: NUM_DST_PLANES,
    };

    let dst_sizes: &mut [usize] = &mut [0usize; NUM_DST_PLANES as usize];
    get_buffers_size(WIDTH, HEIGHT, &dst_format, None, dst_sizes)?;

    let mut dst_rgba: Vec<_> = vec![0u8; dst_sizes[0]];
    let dst_buffers: &mut [&mut [u8]] = &mut [&mut dst_rgba[..]];

    convert_image(
        WIDTH,
        HEIGHT,
        &src_format,
        None,
        src_buffers,
        &dst_format,
        None,
        dst_buffers,
    )?;

    Ok(())
}

Provide image strides to convert data which is not tightly packed:

use dcv_color_primitives as dcp;
use dcp::{convert_image, get_buffers_size, ColorSpace, ImageFormat, PixelFormat};
use std::error;

fn convert() -> Result<(), Box<dyn error::Error>> {
    dcp::initialize();

    const WIDTH: u32 = 640;
    const HEIGHT: u32 = 480;
    const NUM_SRC_PLANES: u32 = 1;
    const NUM_DST_PLANES: u32 = 2;
    const RGB_STRIDE: usize = 4 * (((3 * (WIDTH as usize)) + 3) / 4);

    let src_format = ImageFormat {
        pixel_format: PixelFormat::Bgr,
        color_space: ColorSpace::Lrgb,
        num_planes: NUM_SRC_PLANES,
    };

    let src_strides: &[usize] = &[RGB_STRIDE];

    let src_sizes: &mut [usize] = &mut [0usize; NUM_SRC_PLANES as usize];
    get_buffers_size(WIDTH, HEIGHT, &src_format, Some(src_strides), src_sizes)?;

    let src_rgba: Vec<_> = vec![0u8; src_sizes[0]];
    let src_buffers: &[&[u8]] = &[&src_rgba[..]];

    let dst_format = ImageFormat {
        pixel_format: PixelFormat::Nv12,
        color_space: ColorSpace::Bt709,
        num_planes: NUM_DST_PLANES,
    };

    let dst_sizes: &mut [usize] = &mut [0usize; NUM_DST_PLANES as usize];
    get_buffers_size(WIDTH, HEIGHT, &dst_format, None, dst_sizes)?;

    let mut dst_y: Vec<_> = vec![0u8; dst_sizes[0]];
    let mut dst_uv: Vec<_> = vec![0u8; dst_sizes[1]];
    let dst_buffers: &mut [&mut [u8]] = &mut [&mut dst_y[..], &mut dst_uv[..]];

    convert_image(
        WIDTH,
        HEIGHT,
        &src_format,
        Some(src_strides),
        src_buffers,
        &dst_format,
        None,
        dst_buffers,
    )?;

    Ok(())
}

Structs

Describes how the image data is laid out in memory and its color space.

Enums

An enumeration of supported color models.

An enumeration of errors.

An enumeration of supported pixel formats.

Constants

If a plane stride is assigned to this constant, the plane will be assumed to contain packed data

Functions

Converts from a color space to another one, applying downsampling/upsampling to match destination image format.

Returns a description of the algorithms that are best for the running cpu and available instruction sets

Compute number of bytes required to store an image given its format, dimensions and optionally its strides

Automatically initializes the library functions that are most appropriate for the current processor type.